home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / go32 / mswitch.asm < prev    next >
Assembly Source File  |  1994-07-18  |  11KB  |  537 lines

  1. ; This is file MSWITCH.ASM
  2. ;
  3. ; Copyright (C) 1993 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  4. ;
  5. ; This file is distributed under the terms listed in the document
  6. ; "copying.dj", available from DJ Delorie at the address above.
  7. ; A copy of "copying.dj" should accompany this file; if not, a copy
  8. ; should be available from where this file was obtained.  This file
  9. ; may not be distributed without a verbatim copy of "copying.dj".
  10. ;
  11. ; This file is distributed WITHOUT ANY WARRANTY; without even the implied
  12. ; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. ;
  14.  
  15. ; Modified for VCPI Implement by Y.Shibata Aug 5th 1991
  16. ;    History:191,1
  17.     title    switch between real and protected mode
  18.     .386p
  19.  
  20.     include segdefs.inc
  21.     include tss.inc
  22.     include gdt.inc
  23.     include idt.inc
  24.     include vcpi.inc
  25.  
  26. ;------------------------------------------------------------------------
  27.  
  28.     start_data16
  29.  
  30.     extrn    _gdt:gdt_s
  31.     extrn    _idt:idt_s
  32.     extrn    _gdt_phys:gdt_s
  33.     extrn    _idt_phys:gdt_s
  34.     extrn    _tss_ptr:word
  35.     extrn    _screen_seg:word
  36.     extrn    _use_xms:word
  37.     extrn    _hard_master_lo:byte
  38.     extrn    _hard_master_hi:byte
  39.     extrn    _hard_slave_lo:byte
  40.     extrn    _hard_slave_hi:byte
  41.  
  42.     extrn    _vcpi_installed:word    ;VCPI Installed set this not Zero
  43.     extrn    _vcpi_entry:fword
  44.     extrn    _abs_client:dword
  45.  
  46.     public  _was_exception
  47. _was_exception  dw    0    ; exceptions set this to 1
  48.  
  49.     public  _dr
  50. _dr    label    dword
  51. _dr0    dd    0
  52. _dr1    dd    0
  53. _dr2    dd    0
  54. _dr3    dd    0
  55.     dd    0
  56.     dd    0
  57. _dr6    dd    0
  58. _dr7    dd    0
  59.  
  60.     end_data16
  61.  
  62. ;------------------------------------------------------------------------
  63.  
  64.     .286c
  65.     start_bss
  66.  
  67.     extrn    _i_tss:tss_s
  68.     extrn    _v74_tss:tss_s
  69.     extrn    _v78_tss:tss_s
  70.     extrn    _v79_tss:tss_s
  71.     extrn    _topline_info:word
  72.  
  73.     public  _c_tss, _a_tss, _o_tss, _p_tss, _f_tss, _ed_tss, _r_tss
  74. _c_tss  label    tss_s    ; for "real mode" state
  75.     db    type tss_s dup (?)
  76. _a_tss  label    tss_s    ; for running program
  77.     db    type tss_s dup (?)
  78. _o_tss  label    tss_s    ; for convenience functions
  79.     db    type tss_s dup (?)
  80. _p_tss  label    tss_s    ; for page faults
  81.     db    type tss_s dup (?)
  82. _f_tss  label    tss_s    ; for page handling
  83.     db    type tss_s dup (?)
  84. _ed_tss label    tss_s    ; for external debuggers
  85.     db    type tss_s dup (?)
  86. _r_tss  label    tss_s    ; for real-mode callbacks
  87.     db    type tss_s dup (?)
  88.  
  89. temp_87c    dw    1 dup (?)
  90. temp_87s    dw    1 dup (?)
  91.  
  92.     end_bss
  93.     .386p
  94.  
  95. ;------------------------------------------------------------------------
  96.  
  97. sound    macro
  98.     local    wait_loop
  99.     local    wait_loop1
  100.     mov    al,033h
  101.     out    061h,al
  102.     mov    ecx,100000h
  103. wait_loop:
  104.     loopd    wait_loop
  105.     mov    al,032h
  106.     out    61h,al
  107.     mov    ecx,100000h
  108. wait_loop1:
  109.     loop    wait_loop1
  110.     endm
  111.  
  112.     start_code16
  113.  
  114.     extrn    _xms_local_enable_a20:near
  115.     extrn    _xms_local_disable_a20:near
  116.  
  117. real_stack    dd    ?
  118. real_idt    dw    0400h, 0000h, 0000h
  119. imask1        db    ?
  120. imask2        db    ?
  121.  
  122.     public  _go32
  123. _go32    proc    near
  124.     push    si
  125.     push    di
  126.     push    bx
  127. _go32_1:
  128.     mov    ax,DGROUP
  129.     mov    dx,0
  130.     shld    dx,ax,4
  131.     shl    ax,4
  132.     add    ax,_tss_ptr
  133.     adc    dx,0
  134.     mov    _gdt[g_atss].base0,ax
  135.     mov    _gdt[g_atss].base1,dl
  136.     mov    _gdt[g_atss].base2,dh
  137.     mov    al, 0bdh
  138.     mov    bx,_tss_ptr
  139.     and    byte ptr [bx].tss_eflags+1, al        ; clear NT flag
  140.     and    byte ptr _c_tss.tss_eflags+1,al
  141.     and    byte ptr _i_tss.tss_eflags+1,al
  142.     and    byte ptr _p_tss.tss_eflags+1,al
  143.     and    byte ptr _f_tss.tss_eflags+1,al
  144.     and    byte ptr _v74_tss.tss_eflags+1,al
  145.     and    byte ptr _v78_tss.tss_eflags+1,al
  146.     and    byte ptr _v79_tss.tss_eflags+1,al
  147.     mov    al, 02h
  148.     or    byte ptr _a_tss.tss_eflags+1,al        ; set IE flag for a_tss only
  149.     or    byte ptr _ed_tss.tss_eflags+1,al
  150.  
  151.     mov    al,0fdh
  152.     and    byte ptr _gdt[g_ctss].stype,al        ; clear busy flag
  153.     and    byte ptr _gdt[g_atss].stype,al        ; clear busy flag
  154.     and    byte ptr _gdt[g_itss].stype,al        ; clear busy flag
  155.     and    byte ptr _gdt[g_ptss].stype,al        ; clear busy flag
  156.     and    byte ptr _gdt[g_v74].stype,al        ; clear busy flag
  157.     and    byte ptr _gdt[g_v78].stype,al        ; clear busy flag
  158.     and    byte ptr _gdt[g_v79].stype,al        ; clear busy flag
  159.  
  160.     mov    _was_exception,0
  161.  
  162.     ; set real_stack for return from _go32
  163.     mov    word ptr cs:real_stack,sp
  164.     mov    word ptr cs:real_stack+2,ss
  165.     movzx    esp,sp        ; make sure it's OK
  166.  
  167.     cli
  168.  
  169.     cmp    _topline_info,0
  170.     je    no_topline1
  171.     mov    ax,_screen_seg
  172.     mov    es,ax
  173.     mov    word ptr es:[2], 0b00h+'P'
  174.     mov    word ptr es:[0], 0b00h+' '
  175. no_topline1:
  176.  
  177. ;    in    al,21h
  178. ;    mov    cs:imask1,al
  179.  
  180. ;    in    al,0a1h
  181. ;    mov    cs:imask2,al
  182. ;    or    al,20h
  183. ;    mov    al,0dfh
  184. ;    out    0a1h,al
  185.  
  186.     call    set_a20
  187.     cmp    _vcpi_installed,0
  188.     je    short real_to_protect    ;Not VCPI Mode
  189.     mov    esi,_abs_client
  190.     mov    ax,VCPI_MODE_CHANGE
  191.     int    VCPI_REQ        ;Change Protect Mode
  192. end_loop0:
  193.     jmp    short end_loop0        ;Never Come here!! Safety Loop
  194.  
  195. real_to_protect:
  196.     lgdt    fword ptr _gdt_phys
  197.     lidt    fword ptr _idt_phys
  198.  
  199.     mov    eax,cr0
  200.     or    al,1
  201.     mov    cr0,eax        ; we're in protected mode!
  202.     db    0eah        ; JMP
  203.     dw    offset go_protect_far_jump
  204.     dw    g_rcode
  205. ;
  206. ;    Entry Protect Mode
  207. ;
  208.     public  _protect_entry
  209. _protect_entry  label    near
  210.  
  211. go_protect_far_jump:
  212.     cli
  213.     mov    ax,g_rdata
  214.     mov    ds,ax
  215.     mov    es,ax
  216.     mov    ss,ax
  217.     mov    sp,word ptr cs:real_stack  ;Need VCPI Inialize
  218.     mov    ax,g_core
  219.     mov    fs,ax
  220.     mov    gs,ax
  221.     mov    eax,0
  222.     mov    cr2,eax ; so we can tell INT 0D from page fault
  223.  
  224.  
  225.     mov    eax,_dr0
  226.     mov    dr0,eax
  227.     mov    eax,_dr1
  228.     mov    dr1,eax
  229.     mov    eax,_dr2
  230.     mov    dr2,eax
  231.     mov    eax,_dr3
  232.     mov    dr3,eax
  233.     mov    eax,_dr7
  234.     mov    dr7,eax
  235.  
  236.     cmp    _vcpi_installed,0
  237.     jne    short set_paging_far_jump    ;Now Paging Mode in VCPI
  238.     mov    bx,_tss_ptr
  239.     mov    eax,[bx].tss_cr3
  240.     cmp    eax,0
  241.     je    set_paging_far_jump
  242.     mov    cr3,eax
  243.     mov    eax,cr0
  244.     or    eax,80000000h
  245.     mov    cr0,eax        ; paging enabled!
  246.     db    0eah
  247.     dw    offset set_paging_far_jump
  248.     dw    g_rcode
  249. set_paging_far_jump:
  250.  
  251.     mov    bx,_tss_ptr
  252.     cmp    _vcpi_installed,0
  253.     jne    short no_tss_load    ;Now Paging Mode in VCPI
  254.     mov    ax,g_ctss
  255.     ltr    ax
  256. no_tss_load:
  257.     jmpt    g_atss        ; load state from VCPU
  258.  
  259. _go32    endp
  260.  
  261. ; _go_real_mode must follow the task jump, so a task jump to return
  262. ; is valid
  263.  
  264.     public  _go_real_mode
  265. _go_real_mode    proc    near
  266.  
  267.     cli
  268.     mov    ax,g_rdata
  269.     mov    ds,ax
  270.     mov    es,ax
  271.     mov    fs,ax
  272.     mov    gs,ax
  273.     mov    ss,ax
  274.  
  275.     mov    eax,dr6
  276.     mov    _dr6,eax
  277.     ;
  278.     cmp    _vcpi_installed,0
  279.     je    short protect_to_real
  280.     ;
  281.     clts                ;TS Clear
  282. ;    mov    esp,offset _c_tss.tss_stack    ;Local Stack
  283.     mov    eax,DGROUP
  284.     push    eax            ;GS
  285.     push    eax            ;FS
  286.     push    eax            ;DS
  287.     push    eax            ;ES
  288.     push    eax            ;SS
  289.     movzx    eax,word ptr cs:real_stack
  290.     push    eax            ;ESP
  291.     pushfd                ;EFLAGS
  292.     mov    eax,_TEXT
  293.     push    eax            ;CS
  294.     mov    eax,offset back_to_v86
  295.     push    eax            ;EIP
  296.     movzx    esp,sp
  297.     ;
  298.     mov    ax,g_core
  299.     mov    ds,ax
  300.     mov    ax,VCPI_MODE_CHANGE
  301.     call    fword ptr es:_vcpi_entry
  302. end_loop1:
  303.     jmp    short end_loop1        ;Never Come here!! Safety Loop
  304.  
  305. protect_to_real:
  306.     mov    eax,cr0
  307.     and    eax,07ffffff6h ; clear PE, TS, PG
  308.     mov    cr0,eax
  309.  
  310.     db    0eah
  311.     dw    offset back_to_real_far_jump
  312.     dw    _TEXT
  313. ;
  314. ;    Entry Real Mode
  315. ;
  316. back_to_real_far_jump:
  317.  
  318.     lidt    fword ptr cs:real_idt
  319.     lss    sp,cs:real_stack
  320. back_to_v86:
  321.  
  322. ;    mov    al,cs:imask1
  323. ;    out    21h,al
  324. ;    mov    al,cs:imask2
  325. ;    out    0a1h,al
  326.  
  327.     cmp    _topline_info,0
  328.     je    no_topline2
  329.     mov    ax,_screen_seg
  330.     mov    es,ax
  331.     mov    word ptr es:[0], 0b00h+'R'
  332.     mov    word ptr es:[2], 0b00h+' '
  333. no_topline2:
  334.     mov    ax,DGROUP
  335.     mov    ds,ax
  336.     mov    es,ax
  337.     mov    fs,ax
  338.     mov    gs,ax
  339.  
  340.     call    reset_a20
  341. ;    sti
  342.  
  343.     mov    bx,_tss_ptr
  344.     mov    al,[bx].tss_irqn
  345.  
  346.         mov     cl,_hard_slave_lo
  347.         add     cl,5
  348.         cmp     al,cl
  349.         je      short not_hard  ; for NPX errors
  350.  
  351.     mov    cl,_hard_master_lo
  352.     inc    cl
  353.     cmp    al,cl
  354.     je    short not_hard  ; to check for ^C
  355.  
  356.     cmp    al,_hard_master_lo
  357.     jb    short try_slavepic
  358.     cmp    al,_hard_master_hi
  359.     ja    short try_slavepic
  360.     jmp    is_hard
  361. try_slavepic:
  362.     cmp    al,_hard_slave_lo
  363.     jb    not_hard
  364.     cmp    al,_hard_slave_hi
  365.     ja    not_hard
  366.  
  367. is_hard:
  368.     mov    byte ptr cs:[irq_d+1],al
  369.     jmp    short irq_d_jmp ; to flush the queue
  370. irq_d_jmp:
  371. irq_d    db    0cdh,0        ; generated INT opcode
  372.     jmp    _go32_1
  373.  
  374. not_hard:
  375.     pop    bx
  376.     pop    di
  377.     pop    si
  378.     ret
  379.  
  380. _go_real_mode    endp
  381.  
  382. ;------------------------------------------------------------------------
  383.  
  384. reset_a20    proc    near
  385.     cmp    _vcpi_installed,0
  386.     jne    short reset_a20_nop
  387.     cmp    _use_xms,0
  388.     je    short reset_a20_local
  389.     call    _xms_local_disable_a20
  390. reset_a20_nop:
  391.     ret
  392.  
  393. reset_a20_local:
  394.     in    al,092h        ; 092h is the system control port "A"
  395.                 ; for PS/2 models
  396.     and    al,not 2    ; this resets the A20 bit in register al
  397.     jmp    SHORT $+2    ; forget the instruction fetch
  398.     out    092h,al        ; set the A20 bit off
  399.     ret
  400. reset_a20    endp
  401.  
  402. set_a20 proc    near
  403.     cmp    _vcpi_installed,0
  404.     jne    short set_a20_nop
  405.     cmp    _use_xms,0
  406.     je    short set_a20_local
  407.     call    _xms_local_enable_a20
  408. set_a20_nop:
  409.     ret
  410.  
  411. set_a20_local:
  412.     pushf
  413.     cli
  414.     in    al,092h        ; 092h is the system control port "A"
  415.                 ; for PS/2 models
  416.     or    al,2        ; this sets the A20 bit in register al
  417.     jmp    SHORT $+2    ; forget the instruction fetch
  418.     out    092h,al        ; set the A20 bit on
  419.  
  420.     mov    ax,0
  421.     mov    fs,ax
  422.     mov    ax,0ffffh
  423.     mov    gs,ax
  424.     mov    bx,fs:[0]
  425.     mov    word ptr fs:[0],1234
  426.     cmp    word ptr gs:[16],1234
  427.     je    need_to_set_a20
  428.     mov    word ptr fs:[0],4321
  429.     cmp    word ptr gs:[16],4321
  430.     je    need_to_set_a20
  431.     mov    fs:[0],bx
  432.     popf
  433.     ret
  434.  
  435. need_to_set_a20:
  436.     mov    fs:[0],bx
  437.     call    waitkb
  438.     mov    al,0d1h
  439.     out    64h,al
  440.     call    waitkb
  441.     mov    al,0dfh        ; Patrick
  442.     out    60h,al
  443.     call    waitkb
  444.     mov    al,0ffh        ; Patrick
  445.     out    64h,al        ; Patrick
  446.     call    waitkb        ; Patrick
  447.     mov    ax,0
  448.     mov    fs,ax
  449.     mov    ax,0ffffh
  450.     mov    gs,ax
  451.     mov    bx,fs:[0]
  452.  
  453. wait_for_valid_a20:
  454.     mov    word ptr fs:[0],1234
  455.     cmp    word ptr gs:[16],1234
  456.     je    wait_for_valid_a20
  457.     mov    word ptr fs:[0],4321
  458.     cmp    word ptr gs:[16],4321
  459.     je    wait_for_valid_a20
  460.  
  461.     mov    fs:[0],bx
  462.     popf
  463.     ret
  464.  
  465. waitkb:
  466.     mov    cx,0
  467. waitkb1:
  468.     in    al,64h
  469.     test    al,2
  470.     loopnz  waitkb1
  471.     je    waitkb3
  472. waitkb2:
  473.     in    al,64h
  474.     test    al,2
  475.     loopnz  waitkb1
  476. waitkb3:
  477.     ret
  478. set_a20 endp
  479.  
  480. ;------------------------------------------------------------------------
  481.  
  482.     public    _cpumode    ; 0=real mode, 1=V86
  483. _cpumode:
  484.     smsw    ax
  485.     and    ax,1
  486.     ret
  487.  
  488. ;------------------------------------------------------------------------
  489.  
  490.     public  _cputype    ; from Intel 80486 reference manual
  491. _cputype:
  492.     pushf
  493.     pop    bx
  494.     and    bx,0fffh
  495.     push    bx
  496.     popf
  497.     pushf
  498.     pop    ax
  499.     and    ax,0f000h
  500.     cmp    ax,0f000h
  501.     jz    bad_cpu
  502.     or    bx,0f000h
  503.     push    bx
  504.     popf
  505.     pushf
  506.     pop    ax
  507.     and    ax,0f000h
  508.     jz    bad_cpu
  509.  
  510.     smsw    ax
  511.     test    ax,1
  512.     jnz    bad_mode
  513.     mov    ax,0
  514.     ret
  515.  
  516. bad_mode:
  517.     mov    ax,2
  518.     ret
  519.  
  520. bad_cpu:
  521.     mov    ax,1
  522.     ret
  523.  
  524. ;------------------------------------------------------------------------
  525.  
  526.     end_code16
  527.  
  528. ;------------------------------------------------------------------------
  529.  
  530.     start_code32
  531.  
  532.     end_code32
  533.  
  534. ;------------------------------------------------------------------------
  535.  
  536.     end
  537.